package com.gopay.bis.cmbc.expay.impl;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.bis.cmbc.expay.integrate.Letter;
import com.gopay.bis.cmbc.expay.integrate.PostOffice;
import com.gopay.bis.cmbc.expay.operation.CmbcAdPayParseMessage;
import com.gopay.bis.cmbc.expay.operation.RSAHelper;
import com.gopay.bis.cmbc.expay.operation.SocketTransport;
import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.cmbc.expay.CmbcExPayMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.businesses.ExPayService;

/**
 * 民生代扣
 * 
 * @CmbcAdPayServiceImpl.java
 * @author zhengxue
 * @2015-11-11 下午6:18:52 www.gopay.com.cn Inc.All rights reserved.
 */
public class CmbcAdPayServiceImpl implements ExPayService {
    private final static Logger logger = LoggerFactory.getLogger(CmbcAdPayServiceImpl.class);
    private SocketTransport socketTransport;
    private SocketTransport socketSameTransport;
    private CmbcAdPayParseMessage cmbcAdPayParseMessage;
    private RSAHelper cipher;
    private String privateKey;
    private String publicKey;
    private PostOffice selfBankPostOffice;
    private PostOffice otherBankPostOffice;
    
    @Override
    public Object certification(BaseMessage baseMsg) throws GopayException {
        CmbcExPayMessage message = (CmbcExPayMessage) baseMsg;
        try {
            // 签名
            byte[] signBytes = cipher.signRSA(privateKey, message.getPlainMessage().getBytes("UTF-8"), false, "UTF-8");
            logger.error("CmbcAdPayServiceImpl certification signBytes len: " + signBytes.length);
            // 加密
            byte[] cryptedBytes = cipher.encryptRSA(publicKey, message.getPlainMessage().getBytes("UTF-8"), false,
                    "UTF-8");
            logger.error("CmbcAdPayServiceImpl certification cryptedBytes len: " + cryptedBytes.length);
            // 报文长度 = 合作方编号+ 交易码+ 签名域长度+ 签名域值+ 密文
            int len = message.getPartnerId().getBytes("UTF-8").length + message.getTxnCode().getBytes("UTF-8").length
                    + message.getSighLength().getBytes("UTF-8").length + signBytes.length + cryptedBytes.length;
            String xmlLen = String.valueOf(len);

            while (xmlLen.length() < 8) {
                xmlLen = "0" + xmlLen;
            }
            // 组装byte字节数组请求银行
            List<byte[]> srcArrays = new ArrayList<byte[]>();
            srcArrays.add(xmlLen.getBytes("UTF-8"));
            srcArrays.add(message.getPartnerId().getBytes("UTF-8"));
            srcArrays.add(message.getTxnCode().getBytes("UTF-8"));
            srcArrays.add(message.getSighLength().getBytes("UTF-8"));
            srcArrays.add(signBytes);
            srcArrays.add(cryptedBytes);
            
//            Object resMsg = socketTransport.submit(sysCopy(srcArrays));
//            message = cmbcAdPayParseMessage.parseCrossAdPayResp(message, resMsg);
            Letter letter = new Letter();
            letter.setData(sysCopy(srcArrays));
            otherBankPostOffice.putToSendQueue(letter);
            
        } catch (Exception e) {
            BankLogUtils.printExPaySignExceptionLog(message, e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6076);
        }
        return message;
    }

    @Override
    public Object payment(BaseMessage baseMsg) throws GopayException {
        CmbcExPayMessage message = (CmbcExPayMessage) baseMsg;
        try {
            // 签名
            byte[] signBytes = cipher.signRSA(privateKey, message.getPlainMessage().getBytes("UTF-8"), false, "UTF-8");
            logger.error("CmbcAdPayServiceImpl payment signBytes len: " + signBytes.length);
            // 加密
            byte[] cryptedBytes = cipher.encryptRSA(publicKey, message.getPlainMessage().getBytes("UTF-8"), false,
                    "UTF-8");
            logger.error("CmbcAdPayServiceImpl payment cryptedBytes len: " + cryptedBytes.length);
            // 报文长度 = 合作方编号+ 交易码+ 签名域长度+ 签名域值+ 密文
            int len = message.getPartnerId().getBytes("UTF-8").length + message.getTxnCode().getBytes("UTF-8").length
                    + message.getSighLength().getBytes("UTF-8").length + signBytes.length + cryptedBytes.length;
            String xmlLen = String.valueOf(len);

            while (xmlLen.length() < 8) {
                xmlLen = "0" + xmlLen;
            }
            
            // 组装byte字节数组请求银行
            List<byte[]> srcArrays = new ArrayList<byte[]>();
            srcArrays.add(xmlLen.getBytes("UTF-8"));
            srcArrays.add(message.getPartnerId().getBytes("UTF-8"));
            srcArrays.add(message.getTxnCode().getBytes("UTF-8"));
            srcArrays.add(message.getSighLength().getBytes("UTF-8"));
            srcArrays.add(signBytes);
            srcArrays.add(cryptedBytes);
            
            if (BankConstants.BANK_LOGO_CMBC.equals(message.getBank())) {
                // 同行代扣
//                Object resMsg = socketSameTransport.submit(sysCopy(srcArrays));
//                message = cmbcAdPayParseMessage.parseSameAdPayResp(message, resMsg);
            	Letter letter = new Letter();
                letter.setData(sysCopy(srcArrays));
                selfBankPostOffice.putToSendQueue(letter);
            } else {
                // 跨行代扣
//                Object resMsg = socketTransport.submit(sysCopy(srcArrays));
//                message = cmbcAdPayParseMessage.parseCrossAdPayResp(message, resMsg);
            	Letter letter = new Letter();
                letter.setData(sysCopy(srcArrays));
                otherBankPostOffice.putToSendQueue(letter);
            }
            if(message.getBankOrderId()!=null && message.getTranOrderId()!=null){
                if(!message.getBankOrderId().equals(message.getTranOrderId())){
                    logger.error("lookup----cmbcAdpay pay compareOrder not equal---"+"bankOrderId="+message.getBankOrderId()+"---tranOrderId="+message.getTranOrderId());
                    throw new GopayException(ProcCodeConstants.PROC_CODE_100E6057);
                }
            }
            
        } catch (Exception e) {
            BankLogUtils.printExPaySignExceptionLog(message, e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6057);
        }
        return message;
    }

    @Override
    public Object queryOrder(BaseMessage baseMsg) throws GopayException {
        CmbcExPayMessage message = (CmbcExPayMessage) baseMsg;
        try {
            // 签名
            byte[] signBytes = cipher.signRSA(privateKey, message.getPlainMessage().getBytes("UTF-8"), false, "UTF-8");
            logger.error("CmbcAdPayServiceImpl queryOrder signBytes len: " + signBytes.length);
            // 加密
            byte[] cryptedBytes = cipher.encryptRSA(publicKey, message.getPlainMessage().getBytes("UTF-8"), false,
                    "UTF-8");
            logger.error("CmbcAdPayServiceImpl queryOrder cryptedBytes len: " + cryptedBytes.length);
            // 报文长度 = 合作方编号+ 交易码+ 签名域长度+ 签名域值+ 密文
            int len = message.getPartnerId().getBytes("UTF-8").length + message.getTxnCode().getBytes("UTF-8").length
                    + message.getSighLength().getBytes("UTF-8").length + signBytes.length + cryptedBytes.length;
            String xmlLen = String.valueOf(len);

            while (xmlLen.length() < 8) {
                xmlLen = "0" + xmlLen;
            }
            
            // 组装byte字节数组请求银行
            List<byte[]> srcArrays = new ArrayList<byte[]>();
            srcArrays.add(xmlLen.getBytes("UTF-8"));
            srcArrays.add(message.getPartnerId().getBytes("UTF-8"));
            srcArrays.add(message.getTxnCode().getBytes("UTF-8"));
            srcArrays.add(message.getSighLength().getBytes("UTF-8"));
            srcArrays.add(signBytes);
            srcArrays.add(cryptedBytes);

            String bankBusProd = message.getBankBusProd().value;
            if ((BisBankBusinessProd._19.value).equals(bankBusProd)) {
                // 鉴权查询
                Letter letter = new Letter();
                letter.setData(sysCopy(srcArrays));
                otherBankPostOffice.putToSendQueue(letter);
            } else if ((BisBankBusinessProd._15.value).equals(bankBusProd)
                    && BankConstants.BANK_LOGO_CMBC.equals(message.getBank())) {
                // 同行代扣查询
//                Object resMsg = socketSameTransport.submit(sysCopy(srcArrays));
//                message = cmbcAdPayParseMessage.parseSameAdPayResp(message, resMsg);
            	Letter letter = new Letter();
                letter.setData(sysCopy(srcArrays));
                selfBankPostOffice.putToSendQueue(letter);
            } else {
                // 跨行代扣查询
//                Object resMsg = socketTransport.submit(sysCopy(srcArrays));
//                message = cmbcAdPayParseMessage.parseCrossAdPayResp(message, resMsg);
            	Letter letter = new Letter();
                letter.setData(sysCopy(srcArrays));
                otherBankPostOffice.putToSendQueue(letter);
            }
            
            if(message.getBankOrderId()!=null && message.getTranOrderId()!=null){
                if(!message.getBankOrderId().equals(message.getTranOrderId())){
                    logger.error("lookup----cmbcAdpay query compareOrder not equal---"+"bankOrderId="+message.getBankOrderId()+"---tranOrderId="+message.getTranOrderId());
                    throw new GopayException(ProcCodeConstants.PROC_CODE_100E6058);
                }
            }
        } catch (Exception e) {
            BankLogUtils.printExPaySignExceptionLog(message, e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6058);
        }
        return message;
    }

    @Override
    public Object treatyQuery(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object cancel(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object refund(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object sendSms(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object checkSms(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object queryCvn(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object sign(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object verify(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

    public void setSocketTransport(SocketTransport socketTransport) {
        this.socketTransport = socketTransport;
    }

    public void setCmbcAdPayParseMessage(CmbcAdPayParseMessage cmbcAdPayParseMessage) {
        this.cmbcAdPayParseMessage = cmbcAdPayParseMessage;
    }

    public void setCipher(RSAHelper cipher) {
        this.cipher = cipher;
    }

    public void setSocketSameTransport(SocketTransport socketSameTransport) {
        this.socketSameTransport = socketSameTransport;
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = privateKey;
    }

    public void setPublicKey(String publicKey) {
        this.publicKey = publicKey;
    }


	public void setSelfBankPostOffice(PostOffice selfBankPostOffice) {
		this.selfBankPostOffice = selfBankPostOffice;
	}

	public void setOtherBankPostOffice(PostOffice otherBankPostOffice) {
		this.otherBankPostOffice = otherBankPostOffice;
	}

	/**
     * 系统提供的数组拷贝方法arraycopy
     * */
    public static byte[] sysCopy(List<byte[]> srcArrays) {
        int len = 0;
        for (byte[] srcArray : srcArrays) {
            len += srcArray.length;
        }
        byte[] destArray = new byte[len];
        int destLen = 0;
        for (byte[] srcArray : srcArrays) {
            System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length);
            destLen += srcArray.length;
        }
        logger.error("CmbcAdPayServiceImpl sysCopy length: " + destArray.length);
        return destArray;
    }

    @Override
    public Object signQuery(BaseMessage baseMsg) throws GopayException {
        // TODO Auto-generated method stub
        return null;
    }

}
